home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr05 / xnot12a.zip / KBD.C < prev    next >
C/C++ Source or Header  |  1993-05-20  |  10KB  |  452 lines

  1. #include "jam.h"
  2. #include "stdlib.h"
  3. /*
  4.  *        Terminal independent keyboard handling.
  5.  */
  6. #include    "def.h"
  7. #include    "kbd.h"
  8.  
  9. #define EXTERN
  10. #include    "key.h"
  11.  
  12. #include "macro.h"
  13.  
  14. #ifndef METABIT
  15. # define METABIT 0x80
  16. #endif
  17.  
  18.  
  19. #ifdef    BSMAP
  20. static int bs_map = BSMAP;
  21. /*
  22.  * Toggle backspace mapping
  23.  */
  24. bsmap(f, n)
  25. int f, n;
  26. {
  27.     if(f & FFARG)    bs_map = n > 0;
  28.     else        bs_map = ! bs_map;
  29.     ewprintf("Backspace mapping %sabled", bs_map ? "en" : "dis");
  30.     return TRUE;
  31. }
  32. #endif
  33.  
  34. #ifndef NO_DPROMPT
  35. #define PROMPTL 80
  36.   char    prompt[PROMPTL], *promptp;
  37. #endif
  38.  
  39. static    int    pushed = FALSE;
  40. static    int    pushedc;
  41.  
  42. VOID    ungetkey(c)
  43. int    c;
  44. {
  45.   if(pushed && c==CCHR('[')) 
  46.     pushedc |= METABIT;
  47.   else
  48.     pushedc = c;
  49.   pushed = TRUE;
  50. }
  51.  
  52. int getkey(flag)
  53. int    flag;
  54. {
  55.     int    c;
  56.  
  57. #ifndef NO_DPROMPT
  58.     if(flag && !pushed) {
  59.         if(prompt[0]!='\0' && ttwait()) {
  60.             ewprintf("%s", prompt);    /* avoid problems with % */
  61.             update();        /* put the cursor back     */
  62.             epresf = KPROMPT;
  63.         }
  64.         if(promptp > prompt) 
  65.                   *(promptp-1) = ' ';
  66.     }
  67. #endif
  68.     if(pushed) {
  69.       c = pushedc;
  70.       pushed = FALSE;
  71.       } 
  72.         else        
  73.           c = getkbd();
  74. #ifdef     BSMAP
  75.     if(bs_map)
  76.         if(c==CCHR('H')) 
  77.           c=CCHR('?');
  78.         else if(c==CCHR('?')) 
  79.           c=CCHR('H');
  80. #endif    
  81.  
  82.     if(c & METABIT) {
  83.         pushedc = c & ~METABIT;
  84.         pushed = TRUE;
  85.         c = CCHR('[');
  86.     }
  87.  
  88. #ifndef NO_DPROMPT
  89.     if(flag && promptp < &prompt[PROMPTL - 5]) {
  90.         promptp = mykeyname(promptp, c);
  91.         *promptp++ = '-';
  92.         *promptp = '\0';
  93.     }
  94. #endif
  95.     return c;
  96. }
  97.  
  98. /*
  99.  * doscan scans a keymap for a keyboard character and returns a pointer
  100.  * to the function associated with that character.  Sets ele to the
  101.  * keymap element the keyboard was found in as a side effect.
  102.  */
  103.  
  104. MAP_ELEMENT *ele;
  105.  
  106. PF    doscan(map, c)
  107. register KEYMAP *map;
  108. register int    c;
  109. {
  110.     /* local register copy for faster access 
  111.     */
  112.     register MAP_ELEMENT *elec = &map->map_element[0];
  113.     register MAP_ELEMENT *last = &map->map_element[map->map_num];
  114. #ifndef WINDOWED /* major hack since kbd table out of whack */
  115.   if (c == KEXTEND)
  116.     return (silent_extend);
  117. #endif
  118.     while(elec < last && c > elec->k_num) 
  119.       elec++;
  120.     ele = elec;            /* used by prefix and binding code    */
  121.     if(elec >= last || c < elec->k_base)
  122.       return map->map_default;
  123.     return elec->k_funcp[c - elec->k_base];
  124. }
  125.  
  126. doin()
  127. {
  128.     KEYMAP    *curmap;
  129.     PF    funct;
  130.  
  131. #ifndef NO_DPROMPT
  132.     *(promptp = prompt) = '\0';
  133. #endif
  134.     curmap = curbp->b_modes[curbp->b_nmodes]->p_map;
  135.     key.k_count = 0;
  136.     while((funct=doscan(curmap,(key.k_chars[key.k_count++]=getkey(TRUE))))
  137.         == prefix)
  138.     curmap = ele->k_prefmap;
  139.     if(macrodef && macrocount < MAXMACRO)
  140.       if(funct != (PF)silent_extend)  
  141.         macro[macrocount++].m_funct = funct;
  142.     return (*funct)(0, 1);
  143. }
  144.  
  145. rescan(f, n)
  146. int f, n;
  147. {
  148.     int c;
  149.     register KEYMAP *curmap;
  150.     int i;
  151.     PF    fp;
  152.     int mode = curbp->b_nmodes;
  153.  
  154.     for(;;) {
  155.     if(ISUPPER(key.k_chars[key.k_count-1])) {
  156.         c = TOLOWER(key.k_chars[key.k_count-1]);
  157.         curmap = curbp->b_modes[mode]->p_map;
  158.         for(i=0; i < key.k_count-1; i++) {
  159.           if((fp=doscan(curmap,(key.k_chars[i]))) != prefix) 
  160.                     break;
  161.           curmap = ele->k_prefmap;
  162.         }
  163.         if(fp==prefix) {
  164.           if((fp = doscan(curmap, c)) == prefix)
  165.             while((fp=doscan(curmap,key.k_chars[key.k_count++] =
  166.                 getkey(TRUE))) == prefix)
  167.             curmap = ele->k_prefmap;
  168.         if(fp!=rescan) {
  169. #ifndef NO_MACRO
  170.             if(macrodef && macrocount <= MAXMACRO)
  171.                        if(fp != (PF)silent_extend)  
  172.                  macro[macrocount-1].m_funct = fp;
  173. #endif
  174.             return (*fp)(f, n);
  175.             }
  176.         }
  177.     }
  178.     /* try previous mode */
  179.     if(--mode < 0) 
  180.           {
  181.             /* Using extended commands fouls up
  182.             * the world because cntrl-x 'unknown' recovers
  183.             * by dumping chars to input stream. Ughlest for mouse,
  184.             * refresh, resize, so this hack restarts the aborted/interupting
  185.             * command...
  186.             */
  187.             KCHAR kc = key.k_chars[key.k_count-1];
  188.  
  189.             key.k_count = 0;
  190.             ttflushinput(FALSE);
  191.             if (kc == KEXTEND)
  192.               AddKchar(KEXTEND);
  193.             return ABORT;
  194.           }
  195.  
  196.     curmap = curbp->b_modes[mode]->p_map;
  197.     for(i=0; i < key.k_count; i++) {
  198.         if((fp=doscan(curmap,(key.k_chars[i]))) != prefix) 
  199.               break;
  200.         curmap = ele->k_prefmap;
  201.     }
  202.     if(fp==prefix) {
  203.         while((fp=doscan(curmap,key.k_chars[i++]=getkey(TRUE)))
  204.             == prefix)
  205.         curmap = ele->k_prefmap;
  206.         key.k_count = i;
  207.     }
  208.     if(fp!=rescan && i>=key.k_count-1) {
  209. #ifndef NO_MACRO
  210.         if(macrodef && macrocount <= MAXMACRO)
  211.           if(fp != (PF)silent_extend)  
  212.                 macro[macrocount-1].m_funct = fp;
  213. #endif
  214.         return (*fp)(f, n);
  215.       }
  216.     }
  217. }
  218.  
  219. universal_argument(f, n)
  220. int f, n;
  221. {
  222.     int c, nn=4;
  223.     KEYMAP *curmap;
  224.     PF    funct;
  225.  
  226.     if(f&FFUNIV) nn *= n;
  227.     for(;;) {
  228.     key.k_chars[0] = c = getkey(TRUE);
  229.     key.k_count = 1;
  230.     if(c == '-') 
  231.           return negative_argument(f, nn);
  232.     if(c >= '0' && c <= '9') 
  233.           return digit_argument(f, nn);
  234.  
  235.     curmap = curbp->b_modes[curbp->b_nmodes]->p_map;
  236.     while((funct=doscan(curmap,c)) == prefix) {
  237.         curmap = ele->k_prefmap;
  238.         key.k_chars[key.k_count++] = c = getkey(TRUE);
  239.     }
  240.     if(funct != universal_argument) {
  241. #ifndef NO_MACRO
  242.         if(macrodef && macrocount < MAXMACRO-1) {
  243.         if(f&FFARG) macrocount--;
  244.         macro[macrocount++].m_count = nn;
  245.         macro[macrocount++].m_funct = funct;
  246.         }
  247. #endif
  248.         return (*funct)(FFUNIV, nn);
  249.     }
  250.     nn <<= 2;
  251.     }
  252. }
  253.  
  254. /*ARGSUSED*/
  255. digit_argument(f, n)
  256. int f, n;
  257. {
  258.     int nn, c;
  259.     KEYMAP *curmap;
  260.     PF    funct;
  261.  
  262.     nn = key.k_chars[key.k_count-1] - '0';
  263.     for(;;) {
  264.     c = getkey(TRUE);
  265.     if(c < '0' || c > '9') break;
  266.     nn *= 10;
  267.     nn += c - '0';
  268.     }
  269.     key.k_chars[0] = c;
  270.     key.k_count = 1;
  271.     curmap = curbp->b_modes[curbp->b_nmodes]->p_map;
  272.     while((funct=doscan(curmap,c)) == prefix) {
  273.     curmap = ele->k_prefmap;
  274.     key.k_chars[key.k_count++] = c = getkey(TRUE);
  275.     }
  276. #ifndef NO_MACRO
  277.     if(macrodef && macrocount < MAXMACRO-1) 
  278.       {
  279.         if(f&FFARG) 
  280.           macrocount--;
  281.     else 
  282.           macro[macrocount-1].m_funct = universal_argument;
  283.     macro[macrocount++].m_count = nn;
  284.     macro[macrocount++].m_funct = funct;
  285.       }
  286. #endif
  287.     return (*funct)(FFOTHARG, nn);
  288. }
  289.  
  290. negative_argument(f, n)
  291. int f, n;
  292. {
  293.     int nn = 0, c;
  294.     KEYMAP *curmap;
  295.     PF    funct;
  296.  
  297.     for(;;) {
  298.     c = getkey(TRUE);
  299.     if(c < '0' || c > '9') break;
  300.     nn *= 10;
  301.     nn += c - '0';
  302.     }
  303.     if(nn) 
  304.       nn = -nn;
  305.     else 
  306.       nn = -n;
  307.     key.k_chars[0] = c;
  308.     key.k_count = 1;
  309.     curmap = curbp->b_modes[curbp->b_nmodes]->p_map;
  310.     while((funct=doscan(curmap,c)) == prefix) {
  311.     curmap = ele->k_prefmap;
  312.     key.k_chars[key.k_count++] = c = getkey(TRUE);
  313.     }
  314. #ifndef NO_MACRO
  315.     if(macrodef && macrocount < MAXMACRO-1) 
  316.       {
  317.         if(f&FFARG) 
  318.           macrocount--;
  319.     else 
  320.           macro[macrocount-1].m_funct = universal_argument;
  321.         macro[macrocount++].m_count = nn;
  322.     macro[macrocount++].m_funct = funct;
  323.       }
  324. #endif
  325.     return (*funct)(FFNEGARG, nn);
  326. }
  327.  
  328. /*
  329.  * Insert a character.    While defining a macro, create a "LINE" containing
  330.  * all inserted characters.
  331.  */
  332.  
  333. selfinsert(f, n)
  334. int f, n;
  335. {
  336.     register int c;
  337.     int count;
  338. #ifndef NO_MACRO
  339.     LINE *lp;
  340. #endif
  341.  
  342.     if (curbp->b_flag & BFVIEW)
  343.      {
  344.        ttbeep();
  345.        return FALSE;
  346.      }
  347.  
  348.   if (filetimechanged(curbp))
  349.     return(FALSE);
  350.  
  351.   clearUndo(curbp);
  352.   if ((curbp->b_flag & BFOVERWRITE) == 0)
  353.       cacheInsert((RSIZE)n);   /* no undo for overwrite (yet) */
  354.  
  355.     if (n < 0)    
  356.       return FALSE;
  357.     if (n == 0) 
  358.       return TRUE;
  359.     c = key.k_chars[key.k_count-1];
  360.  
  361.     if(macrodef && macrocount < MAXMACRO) {
  362.     if(f & FFARG) 
  363.       macrocount -= 2;
  364.     if(lastflag & CFINS) {    /* last command was insert -- tack on end */
  365.         macrocount--;
  366.         if(maclcur->l_size < maclcur->l_used + n) {
  367.         if((lp = lallocx(maclcur->l_used + n)) == NULL)
  368.             return FALSE;
  369.         lp->l_fp = maclcur->l_fp;
  370.         lp->l_bp = maclcur->l_bp;
  371.         lp->l_fp->l_bp = lp->l_bp->l_fp = lp;
  372.         bcopy(maclcur->l_text, lp->l_text, (size_t)maclcur->l_used);
  373.         for(count = maclcur->l_used; count < lp->l_used; count++)
  374.             lp->l_text[count] = (char)c;
  375.         free((char *)maclcur);
  376.         maclcur = lp;
  377.         } else {
  378.         maclcur->l_used += n;
  379.         for(count = maclcur->l_used-n; count < maclcur->l_used; count++)
  380.             maclcur->l_text[count] = (char)c;
  381.         }
  382.     } else {
  383.         macro[macrocount-1].m_funct = insert;
  384.         if((lp = lallocx(n)) == NULL) 
  385.         return FALSE;
  386.         lp->l_bp = maclcur;
  387.         lp->l_fp = maclcur->l_fp;
  388.         maclcur->l_fp = lp;
  389.         maclcur = lp;
  390.         for(count = 0; count < n; count++)
  391.         lp->l_text[count] = (char)c;
  392.     }
  393.     thisflag |= CFINS;
  394.     }
  395.  
  396.     /* do work
  397.     */
  398.     if(c == '\n') {
  399.     do {
  400.         count = lnewline();
  401.     } while (--n && count==TRUE);
  402.     return count;
  403.     }
  404.  
  405.     if(curbp->b_flag & BFOVERWRITE) {        /* Overwrite mode    */
  406.     lchange(WFEDIT);
  407.         changelineflag(curwp->w_dotp, TRUE);
  408.     while(curwp->w_doto < llength(curwp->w_dotp) && n--)
  409.       lputc(curwp->w_dotp, curwp->w_doto++, (char)c);
  410.     if(n<=0) 
  411.       return TRUE;
  412.     }
  413.     {
  414.     int s = linsert(n, c);
  415.  
  416.     /* special case major hack for autoindent
  417.      */
  418. #if 0
  419.     if (s)
  420.       {
  421.         if ((n == 1) && (c == '}'))
  422.           alignindent(0, 1);
  423.       }
  424. #endif
  425.     return(s);
  426.     }
  427. }
  428.  
  429. /*
  430.  * this could be implemented as a keymap with everthing defined
  431.  * as self-insert.
  432.  */
  433. quote(f, n)
  434. int f, n;
  435. {
  436.     register int c;
  437.  
  438.     key.k_count = 1;
  439.     if((key.k_chars[0] = getkey(TRUE)) >= '0' && key.k_chars[0] <= '7') {
  440.     key.k_chars[0] -= (int)'0';
  441.     if((c = getkey(TRUE)) >= (int)'0' && c <= (int)'7') {
  442.         key.k_chars[0] <<= 3;
  443.         key.k_chars[0] += c - (int)'0';
  444.         if((c = getkey(TRUE)) >= (int)'0' && c <= (int)'7') {
  445.           key.k_chars[0] <<= 3;
  446.           key.k_chars[0] += c - (int)'0';
  447.         } else ungetkey(c);
  448.     } else ungetkey(c);
  449.     }
  450.     return selfinsert(f, n);
  451. }
  452.